package com.cnswhy.cloud.server.iot.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

@Slf4j
public class HttpUtils
{
    

  //请求超时时间,这个时间定义了socket读数据的超时时间，也就是连接到服务器之后到从服务器获取响应数据需要等待的时间,发生超时，会抛出SocketTimeoutException异常。
    private static final int SOCKET_TIME_OUT = 60000;
    
    //连接超时时间,这个时间定义了通过网络与服务器建立连接的超时时间，也就是取得了连接池中的某个连接之后到接通目标url的连接等待时间。发生超时，会抛出ConnectionTimeoutException异常
    private static final int CONNECT_TIME_OUT = 60000;

    public static String map2XML(Map<String,Object> dataMap){
        StringBuilder strBuilder = new StringBuilder();
        strBuilder.append("<xml>");
        Set<String> objSet = dataMap.keySet();
        for (Object key : objSet){
            if (key == null){
                continue;
            }
            strBuilder.append("<").append(key.toString()).append(">");
            Object value = dataMap.get(key);
            strBuilder.append(value);
            strBuilder.append("</").append(key.toString()).append(">\n");
        }
        strBuilder.append("</xml>");
        System.out.println("xml内容:"+strBuilder);
        return strBuilder.toString();
    }
    public static String sendPost(String url, Map<String,Object> xmlObj) throws IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {

        String result = null;

        HttpPost httpPost = new HttpPost(url);


        //得指明使用UTF-8编码，否则到API服务器XML的中文不能被成功识别
        StringEntity postEntity = new StringEntity(map2XML(xmlObj), "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.setEntity(postEntity);
//        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SOCKET_TIME_OUT)
                .setConnectTimeout(CONNECT_TIME_OUT).build();
        //设置请求器的配置
        httpPost.setConfig(requestConfig);

        log.info("executing request" + httpPost.getRequestLine());

        try {
            CloseableHttpClient httpClient = HttpClients.custom().build();
            HttpResponse response = httpClient.execute(httpPost);

            HttpEntity entity = response.getEntity();

            result = EntityUtils.toString(entity, "UTF-8");
        } catch (ConnectionPoolTimeoutException e) {
            log.error("http get throw ConnectionPoolTimeoutException(wait time out)");

        } catch (ConnectTimeoutException e) {
            log.error("http get throw ConnectTimeoutException");

        } catch (SocketTimeoutException e) {
            log.error("http get throw SocketTimeoutException");

        } catch (Exception e) {
            log.error("http get throw Exception");

        } finally {
            httpPost.abort();
        }

        return result;
    }
    
    /**
     * post请求
     * 
     * @param url
     * @param jsonString
     * @return
     */
    public static String httpPost(String url, String jsonString)
    {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        CloseableHttpResponse httpResponse = null;
        try
        {
            post.setEntity(new ByteArrayEntity(jsonString.getBytes("UTF-8")));
            httpResponse = httpClient.execute(post);
            if (httpResponse != null && httpResponse.getStatusLine().getStatusCode() == 200)
            {
                result = EntityUtils.toString(httpResponse.getEntity(), "utf-8");
            }
            return result;
        }
        catch (Exception e)
        {
            log.error("<---HTTP POST 请求报错，URL:" + url, e);
        }
        finally
        {
            try
            {
                httpClient.close();
                if (httpResponse != null)
                {
                    httpResponse.close();
                }
            }
            catch (IOException e)
            {
                log.error("close http client error!!", e);
            }
        }
        return null;
    }
    
    /**
     * 
    * @Description: 
    * @param @param url
    * @param @param jsonString
    * @param @return    设定文件  
    * @return String    返回类型  
    * @throws
     */
    public static String httpPost(String url, Map<String,String> params)
    {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        CloseableHttpResponse httpResponse = null;
        try
        {
            //装填参数
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            if(params!=null){
                for (Entry<String, String> entry : params.entrySet()) {
                    nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
            }
            //设置参数到请求对象中
            post.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
            
            httpResponse = httpClient.execute(post);
            if (httpResponse != null && httpResponse.getStatusLine().getStatusCode() == 200)
            {
                result = EntityUtils.toString(httpResponse.getEntity(), "utf-8");
            }
            return result;
        }
        catch (Exception e)
        {
            log.error("<---HTTP POST 请求报错，URL:" + url, e);
        }
        finally
        {
            try
            {
                httpClient.close();
                if (httpResponse != null)
                {
                    httpResponse.close();
                }
            }
            catch (IOException e)
            {
                log.error("close http client error!!", e);
            }
        }
        return null;
    }    
    

    
    
    /**
     * 发送http get请求
     * 
     * @param getUrl
     * @return
     */
    public static String sendGetRequest(String getUrl)
    {
        StringBuffer sb = new StringBuffer();
        InputStreamReader isr = null;
        BufferedReader br = null;
        try
        {
            URL url = new URL(getUrl);
            URLConnection urlConnection = url.openConnection();
            urlConnection.setAllowUserInteraction(false);
            isr = new InputStreamReader(url.openStream(), "UTF-8");
            br = new BufferedReader(isr);
            String line;
            while ((line = br.readLine()) != null)
            {
                sb.append(line);
            }
        }
        catch (IOException e)
        {
            log.error("http get 请求出错", e);
        }
        finally
        {
            try
            {
                if (isr != null)
                {
                    isr.close();
                }
                if (br != null)
                {
                    br.close();
                }
            }
            catch (Exception e)
            {
                log.error("关闭流出错", e);
            }
        }
        return sb.toString();
    }
    
    /**
     * 请求url下载字节数组（get请求）
     * 
     * @author lixiao
     * @date 2018/04/18
     * @param url
     * @return
     */
    public static byte[] download(String url)
    {
        
        byte[] result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try
        {
            log.info("下载图片url=" + url);
            HttpGet httpGet = new HttpGet(url);
            // 设置请求和传输超时时间
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(10000).build();
            httpGet.setConfig(requestConfig);
            
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            if (entity != null)
            {
                result = EntityUtils.toByteArray(entity);
            }
            httpGet.abort();
        }
        catch (Exception e)
        {
            log.error("HttpClient请求出错！", e);
        }
        finally
        {
            try
            {
                httpClient.close();
            }
            catch (IOException e)
            {
                log.error("关闭CloseableHttpClient异常！", e);
            }
        }
        return result;
    }
    
    /**
     * 描述：get方式请求
     * 作者：张进飞
     * 时间：2018年5月7日 下午8:30:30
     * @param url
     * @return
     * @throws Exception
     */
    public static String httpGetConnect(String url) throws Exception
    {
        return httpGetConnect(url, "UTF-8");
    }
    
    /**
     * 描述：get方式请求
     * 作者：张进飞
     * 时间：2018年5月7日 下午8:30:11
     * @param url
     * @param encoding
     * @return
     * @throws Exception
     */
    public static String httpGetConnect(String url, String encoding) throws Exception
    {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet get = new HttpGet(url);
        CloseableHttpResponse httpResponse = null;
        try
        {
            httpResponse = httpClient.execute(get);
            if (httpResponse != null && httpResponse.getStatusLine().getStatusCode() == 200)
            {
                result = EntityUtils.toString(httpResponse.getEntity(), encoding);
            }
            return result;
        }
        catch (Exception e)
        {
            log.error("<---HTTP POST 请求报错，URL:" + url, e);
        }
        finally
        {
            try
            {
                httpClient.close();
                if (httpResponse != null)
                {
                    httpResponse.close();
                }
            }
            catch (IOException e)
            {
                log.error("close http client error!!", e);
            }
        }
        return null;
    }
}
